const template = document.createElement("template");

template.innerHTML = /*html*/ `
<style>
  :host {
    display: block;
    font-size: 13px;
    width: 100%;
    height: 100%;
    transition: all 0.5s linear;
  }
  :host *{
    box-sizing: border-box;
  }

  /* 滚动槽 */
  ::-webkit-scrollbar {
    width: 6px;
    height: 6px;
  }
  ::-webkit-scrollbar-track {
    border-radius: 3px;
    background: transparent;
    -webkit-box-shadow: inset 0 0 5px transparent;
  }
  /* 滚动条滑块 */
  ::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background: rgba(0,0,0,0.12);
    -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.2);
  }

  ul,li{
    padding: 0;
    margin: 0;
    list-style: none;
  }
  .notes-box{
    width: 100%;
    height: 100%;
    overflow-y: auto;
  }
  .todo-box{
    width: 100%;
    height: calc(100% - 30px);
    overflow-y: auto;
  }

  .null{
    width: 100%;
    height: calc(100% - 30px);
    padding: 10px;
    color: rgba(160, 160, 160, 0.6);
  }

  .unfinished{
    width: 100%;
    overflow: hidden;
  }
  li{
    --padding: 10px;
    width: 100%;
    position: relative;
    padding: calc(var(--padding) / 2) var(--padding);
    padding-right: 5px;
  }
  li ~ li{
    border-top: 1px solid rgba(255, 255, 255, 0.2);
  }
  li:hover{
    background-color: rgba(0, 0, 0, 0.05);
  }

  li .icons{
    position: absolute;
    right: -50px;
    top: 0;
    display: flex;
    height: 100%;
    align-items: center;
    transition: all 0.4s;
    font-size: 14px;
    cursor: pointer;
  }

  li:hover .icons{
    right: 10px;
  }

  .checked-box{
    position: absolute;
    left: var(--padding);
    top: calc(var(--padding) / 2 + .4em);
    width: 1em;
    height: 1em;
    border: 1px solid var(--theme-week-bg);
    border-radius: 0.2em;
  }
  .move{
    position: absolute;
    left: var(--padding);
    top: calc(var(--padding) / 2 + .2em);
    width: 1em;
    height: 1em;
    border-radius: 0.2em;
    display: none;
  }
  .todo-content{
    text-indent: 1.5em;
    border: none;
    outline: none;
    word-break: break-all;
    user-select: none;
    width: 100%;
    line-height: 1.7em;
    min-height: calc(1em + 3px);
  }
  .checked{
    animation: through;
    animation-duration: 0.3s;
    animation-timing-function: linear;
    animation-fill-mode: forwards;
    border: none;
  }
  .checked .checked-box{
    background-image: url('../components/IconSvg/correct.svg');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-position: center;
  }
  .checked .todo-content{
    text-decoration: line-through;
  }
  .mobile-mode .checked-box{
    display: none;
  }
  .mobile-mode .move{
    display: block;
  }
  @keyframes through {
    0% {
      transform: scale(1);
      opacity: 1;
      display: block;
    }
    99% {
      transform: scale(0);
      opacity: 0;
      display: block;
    }
    100%{
      transform: scale(0);
      opacity: 0;
      display: none;
    }
  }
  .completed{
    width: 100%;
    overflow: hidden;
    padding-top: 5px;
  }
  .completed .completed-title{
    width: 100%;
    padding: 10px;
    user-select: none;
    display: flex;
    align-items: center;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
  }

  .completed .completed-title icon-svg{
    transform: rotate(-90deg);
    margin-right: 10px;
  }

  .completed ul{
    display: none;
  }
  .completed .checked-box{
    background-image: url('../components/IconSvg/correct.svg');
    background-size: 100% 100%;
    background-repeat: no-repeat;
    background-position: center;
    opacity: 0.3;
  }
  .completed .todo-content{
    text-decoration: line-through;
    width: 100%;
    color: rgba(0,0,0, 0.3);
    min-height: 1em;
  }
  .todo-content:empty:before{
    content: attr(data-placeholder);
    color: rgba(160, 160, 160, 0.6);
    display: block; 
  }
  .todo-content:focus:before,
  .todo-content:not(:empty):before {
    content: none;
  } 
  .completed.expand ul{
    display: block;
  }

  .completed.expand .completed-title icon-svg{
    transform: rotate(90deg);
  }

  .todo-footer{
    width: 100%;
    height: 30px;
    padding: 5px 10px;
    user-select: none;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
    font-size: 12px;
  }
</style>
<div class="notes-box">
  <div class="null">
    新增一条：双击空白处，或双击底部栏目位置
  </div>
  <div class="todo-box">
    <ul class="unfinished">
      <li>
        <div class="checked-box"></div>
        <div class="todo-content" contenteditable="plaintext-only">1.新增待办：点击某条待办后按Enter键，或点顶部+号，或双击底部栏目位置</div>
      </li>
      <li>
        <div class="checked-box"></div>
        <div class="todo-content" contenteditable="plaintext-only">2.新增待办：点击某条待办后按Enter键，或点顶部+号，或双击底部栏目位置</div>
      </li>
    </ul>
    <div class="completed expand">
      <div class="completed-title"> <icon-svg name="backward"></icon-svg> 已完成</div>
      <ul>
      </ul>
    </div>
  </div>
  <div class="todo-footer">待办</div>
</div> 
`;


export default class Notes extends HTMLElement {
  static observedAttributes = [ "mobile-mode", "value"];
  constructor() {
    super();
    this.value = {
      unfinished: [
        {
          content: '1.新增待办：点击某条待办后按Enter键，或点顶部+号，或双击底部栏目位置',
          remind: false,
          remindTime: 0,
          repeat: {
            type: '',
            days: []
          },
        }
      ],
      completed: [
        {
          content: '4.新增待办：点击某条待办后按Enter键，或点顶部+号，或双击底部栏目位置',
          remind: false,
          remindTime: 0,
          repeat: {
            type: '',
            days: []
          }
        }
      ]
    };
    this.focusIndex = undefined;
    this.mobileMode = false;
    const shadow = this.attachShadow({ mode: "open" });
    const content = template.content.cloneNode(true); 

    this.null_el = content.querySelector('.null');
    this.todobox_el = content.querySelector('.todo-box');
    this.unfinished_el = content.querySelector('.unfinished');
    this.completed_el = content.querySelector('.completed ul');

    content.querySelector('.completed-title').ondblclick = e => e.stopPropagation();
    content.querySelector('.completed-title').onclick = (e) => {
      e.stopPropagation();
      this.shadowRoot.querySelector('.completed').classList.toggle('expand');
    }

    this.null_el.ondblclick = (e) => {
      this.focusIndex = this.value.unfinished.length;
      this.value.unfinished.push({
        content: '',
        remind: false,
        remindTime: 0,
        repeat: {
          type: '',
          days: []
        }
      })
      this.renderList();
    }

    content.querySelector('.todo-box').ondblclick = (e) => {
      this.focusIndex = this.value.unfinished.length;
      this.value.unfinished.push({
        content: '',
        remind: false,
        remindTime: 0,
        repeat: {
          type: '',
          days: []
        }
      })
      this.renderList();
    }

    content.querySelector('.todo-footer').ondblclick = () => {
      this.focusIndex = this.value.unfinished.length;
      this.value.unfinished.push({
        content: '',
        remind: false,
        remindTime: 0,
        repeat: {
          type: '',
          days: []
        }
      })
      this.renderList();
    }
    this.renderList();
    this.renderCompletedList();
    shadow.appendChild(content);
  }

  renderList(){
    let nullAll = [...this.value.unfinished, ...this.value.completed]
    
    if(nullAll.length === 0){
      this.null_el.style.display = 'block';
      this.todobox_el.style.display = 'none';
      return;
    }else{
      this.null_el.style.display = 'none';
      this.todobox_el.style.display = 'block';
    }
    this.unfinished_el.innerHTML  = this.value.unfinished.map(item=>{
      return `
        <li draggable="${this.mobileMode}">
          <div class="checked-box"></div>
          <div class="move"><icon-svg name="move"></icon-svg></div>
          <div class="todo-content" data-placeholder="请输入.../Enter新建/Shift+Enter换行"  contenteditable="false">${item.content}</div>
          <div class="icons"><icon-svg name="closure"></div>
        </li>
      `
    }).join('');
    this.unfinished_el.ondblclick = (e) => {
      e.stopPropagation();
      
    }
    let lis = [...this.unfinished_el.querySelectorAll('li')].forEach((item, index)=>{
      let todoContentEl = item.querySelector('.todo-content');

      if(index === this.focusIndex){
        todoContentEl.contentEditable = 'plaintext-only';
        todoContentEl.focus();
        this.focusIndex = undefined;
      };

      if(this.mobileMode){
        item.ondragstart = (e)=>{
          e.dataTransfer.setData('text/plain', index);
          e.dataTransfer.setData('type/plain', 'unfinished');
        }
        item.ondragover = (e)=>{
          e.preventDefault();
          e.dataTransfer.dropEffect = "move";
        }

        const directionInsert = (e) => {
          let height = e.currentTarget.offsetHeight;
          if (e.layerY < height / 2) {
            return 'beforebegin'
          } else {
            return 'afterend'
          }
        }

        item.ondrop = (e)=>{
          e.stopPropagation();
          let currentType = 'unfinished'
          let dropIndex = index;
          let dragIndex = parseInt(e.dataTransfer.getData('text/plain'));
          let type = e.dataTransfer.getData('type/plain');
          
          let direction = directionInsert(e);
          
          if(direction === 'beforebegin'){
            dropIndex = index;
          }else{
            dropIndex = index + 1;
          }
          
          if(type === currentType && dropIndex === dragIndex) return;
          let temp = {...this.value.unfinished[dragIndex]};
          
          if(dropIndex < dragIndex && type === currentType){
            this.value.unfinished.splice(dragIndex, 1);
            this.value.unfinished.splice(dropIndex, 0, temp);
          }else if(dropIndex > dragIndex && type === currentType){
            this.value.unfinished.splice(dropIndex, 0, temp);
            this.value.unfinished.splice(dragIndex, 1);
          }

          if(type !== currentType){
            let un = this.value.completed.splice(dragIndex, 1);
            this.value.unfinished.splice(dropIndex, 0, un[0]);
          }

          this.dispatchEventHandler();
          this.renderList();
          this.renderCompletedList();
        }
        return;
      }

      todoContentEl.ondblclick = (e) => {
        e.stopPropagation();
        todoContentEl.contentEditable = 'plaintext-only';
        todoContentEl.focus();
      }


      todoContentEl.onblur = (e) => {
        todoContentEl.contentEditable = false;
      }

      item.querySelector('.checked-box').onclick = () => {
        item.classList.add('checked')
        confetti({
          particleCount: 100,
          spread: 70,
          origin: { y: 0.6 }
        })
        let completedValue = this.value.unfinished.splice(index, 1);
        this.value.completed.push(...completedValue);
        this.dispatchEventHandler();
      };

      item.onanimationend = ()=>{
        this.renderList();
        this.renderCompletedList();
      }

      todoContentEl.oninput = (e) => {
        this.value.unfinished[index].content = e.target.innerText;
        this.dispatchEventHandler();
      }

      todoContentEl.onkeydown = (e) => {

        if(e.keyCode === 13 && !e.target.innerText.trim()){
          e.preventDefault();
          return;
        };
        
        if(e.keyCode === 8 && !e.target.innerText.trim()){
          e.preventDefault();
          
          this.value.unfinished.splice(index, 1);
          this.dispatchEventHandler();
          this.renderList();
          return;
        };

        if(e.shiftKey && e.keyCode === 13)return;
        if(e.keyCode === 13 && e.target.innerText.trim()){
          e.preventDefault();
          this.value.unfinished.splice(index + 1, 0,  {
            content: '',
            remind: false,
            remindTime: 0,
            repeat: {
              type: '',
              days: []
            }
          });
          this.focusIndex = index + 1;
          this.dispatchEventHandler();
          this.renderList();
          
        }
      }

    })

    let icons = [...this.unfinished_el.querySelectorAll('icon-svg[name=closure]')].forEach((item,index)=>{
      item.onclick = ()=>{
        this.value.unfinished.splice(index,1);
        this.renderList();
        this.renderCompletedList();
        this.dispatchEvent(new CustomEvent("change", {
          detail: {
            value: this.value
         }
        }))
      }
    })
  }

  renderCompletedList(){
    this.completed_el.innerHTML  = this.value.completed.map(item=>{
      return `
        <li draggable="${this.mobileMode}">
          <div class="checked-box"></div>
          <div class="move"><icon-svg name="move"></icon-svg></div>
          <div class="todo-content">${item.content}</div>
          <div class="icons"><icon-svg name="closure"></div>
        </li>
      `
    }).join('')

    this.completed_el.ondblclick = (e) => {
      e.stopPropagation();
      
    }
    let lis = [...this.completed_el.querySelectorAll('li')].forEach((item, index)=>{
      item.querySelector('.checked-box').onclick = () => {
        item.classList.add('checked')
        let unfinishedValue = this.value.completed.splice(index, 1);
        this.value.unfinished.push(...unfinishedValue);
        this.dispatchEventHandler();
      };

      if(this.mobileMode){
        item.ondragstart = (e)=>{
          e.dataTransfer.setData('text/plain', index);
          e.dataTransfer.setData('type/plain', 'completed');
        }
        item.ondragover = (e)=>{
          e.preventDefault();
          e.dataTransfer.dropEffect = "move";
        }
        const directionInsert = (e) => {
          let height = e.currentTarget.offsetHeight;
          if (e.layerY < height / 2) {
            return 'beforebegin'
          } else {
            return 'afterend'
          }
        }
        item.ondrop = (e)=>{
          e.stopPropagation();
           let currentType = 'completed'
          let dropIndex = index;
          let dragIndex = parseInt(e.dataTransfer.getData('text/plain'));
          let type = e.dataTransfer.getData('type/plain');
          let direction = directionInsert(e)
          if(direction === 'beforebegin'){
            dropIndex = index;
          }else{
            dropIndex = index + 1;
          }
          if(type === currentType && dropIndex === dragIndex) return;
          let temp = {...this.value.completed[dragIndex]};
          
          if(dropIndex < dragIndex && type === currentType){
            this.value.completed.splice(dragIndex, 1);
            this.value.completed.splice(dropIndex, 0, temp);
          }else if(dropIndex > dragIndex && type === currentType){
            this.value.completed.splice(dropIndex, 0, temp);
            this.value.completed.splice(dragIndex, 1);
          }
          console.log(type, currentType);
          
          if(type !== currentType){
            let com = this.value.unfinished.splice(dragIndex, 1);
            this.value.completed.splice(dropIndex, 0, com[0]);
          }
          this.dispatchEventHandler();
          this.renderList();
          this.renderCompletedList();
        }
        return;
      }

      item.onanimationend = ()=>{
        this.renderList();
        this.renderCompletedList();
      }

    })

    let icons = [...this.completed_el.querySelectorAll('icon-svg[name=closure]')].forEach((item,index)=>{
      item.onclick = ()=>{
        this.value.completed.splice(index,1);
        this.renderList();
        this.renderCompletedList();
        this.dispatchEvent(new CustomEvent("change", {
          detail: {
            value: this.value
         }
        }))
      }
    })
  }

  dispatchEventHandler () {
    this.dispatchEvent(new CustomEvent("change", {
      detail: {
        value: this.value,
      },
    }));
  }

  connectedCallback () {
  }

  attributeChangedCallback(name, oldValue, newValue) {
    console.log(name);
    
    if(name === 'mobile-mode'){
      console.log(newValue);
      
      this.mobileMode = newValue === 'true';
      if(this.mobileMode){
        [...this.shadowRoot.querySelectorAll('ul')].forEach(item=>{
          item.classList.add('mobile-mode');
        })
      }else{
        [...this.shadowRoot.querySelectorAll('ul')].forEach(item=>{
          item.classList.remove('mobile-mode');
        })
      }
      this.renderList();
      this.renderCompletedList();
    }

    if(name === 'value'){
      this.value = JSON.parse(newValue);
      this.renderList();
      this.renderCompletedList();
    }
  }
  
}